/**
 *  Copyright 2002-2009 the original author or authors.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package foo.bar.blog.web.extension;

import foo.bar.blog.web.action.Calendar;
import foo.bar.blog.web.action.DayEnum;
import foo.bar.blog.web.action.MonthEnum;
import net.sourceforge.stripes.validation.TypeConverter;
import net.sourceforge.stripes.validation.ValidationError;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.*;

/**
 * Convert following string request into a {@link Calendar} object.
 *
 * - <day>_<month>_<year> eg. 13_JANUARY_2009
 * - <month>_<year> eg. FEBRUARY_2009
 * - <year> eg. 2009
 *
 * Ungiven day will be assumed to be 1st, ungiven month will assumed to be JANUARY, ungiven year
 * will be assumed to be 2008.
 *
 * @see {@link Calendar}
 * @see {@link foo.bar.blog.web.action.MonthEnum}
 * @see {@link foo.bar.blog.web.action.DayEnum}
 *
 * @author tmjee
 * @version $Date: 2009-03-14 06:53:07 +0000 (Sat, 14 Mar 2009) $ $Id$
 */
public class CalendarTypeConverter implements TypeConverter<Calendar> {

    private static final Log LOG = LogFactory.getLog(CalendarTypeConverter.class);

    public void setLocale(Locale locale) {
    }

    public Calendar convert(String input, Class<? extends Calendar> targetType, Collection<ValidationError> errors) {

        if ((input == null) || (input.trim().length() <= 0)) {
            return null;
        }
        List<String> tokenizedInput = new ArrayList<String>();
        StringTokenizer tokenizer = new StringTokenizer(input, "_");
        while(tokenizer.hasMoreTokens()) {
            tokenizedInput.add(tokenizer.nextToken());
        }

        if (tokenizedInput.size() > 3) {
            LOG.error("input ["+input+"] is in an unrecongnized format");
            return null;
        }


        DayEnum day = null;
        MonthEnum month = null;
        int year = 0;

        if (tokenizedInput.size() == 3) { // we have day_month_year
            String _day = tokenizedInput.get(0);
            String _month = tokenizedInput.get(1);
            try {
                year = Integer.valueOf(tokenizedInput.get(2));
            }
            catch(NumberFormatException e) {
                LOG.error("unable to reconized year ["+tokenizedInput.get(2)+"]", e);
                return null;
            }
            try {
                day = DayEnum.convert(Integer.valueOf(_day));
            }
            catch(NumberFormatException e) {
                LOG.error("unable to recongnize day ["+_day+"]", e);
                return null;
            }
            month = MonthEnum.convert(_month);
        }
        if (tokenizedInput.size() == 2) { // we have month_year
            String _month = tokenizedInput.get(0);
            try {
                year = Integer.valueOf(tokenizedInput.get(1));
            }
            catch(NumberFormatException e) {
                LOG.error("unable to reconized year ["+tokenizedInput.get(2)+"]");
                return null;
            }
            month = MonthEnum.convert(_month);
        }
        if (tokenizedInput.size() == 1) { // we have year
            try {
                year = Integer.valueOf(tokenizedInput.get(0));
            }
            catch(NumberFormatException e) {
                LOG.error("unable to reconized year ["+tokenizedInput.get(2)+"]");
                return null;
            }
        }


        try {
            java.util.Calendar calendar = java.util.Calendar.getInstance();
            calendar.setLenient(false);
            if (day != null) {
                calendar.set(java.util.Calendar.DAY_OF_MONTH, day.day());
            }
            else {
                calendar.set(java.util.Calendar.DAY_OF_MONTH, 1);
            }
            if (month != null) {
                calendar.set(java.util.Calendar.MONTH, month.month());
            }
            else {
                calendar.set(java.util.Calendar.MONTH, MonthEnum.JANUARY.month());
            }
            if (year > 0) {
                calendar.set(java.util.Calendar.YEAR, year);
            }
            else {
                calendar.set(java.util.Calendar.YEAR, 2008);
            }
            calendar.getTime();
        }
        catch(Exception e) {
            LOG.error("cannot conver this input ["+input+"] into a valid date", e);
        }

        Calendar cal = new Calendar();
        if (day != null) {
            cal.setDay(day);
        }
        if (month != null) {
            cal.setMonth(month);
        }
        if (year > 0) {
            cal.setYear(year);
        }

        return cal;
    }
}
